; ========================================================================
;本节内容由周靓颀&曹凌霄提供，黄铭整理。
; ========================================================================
; 全局变量定义部分
; ------------------------------------------------------------------------
; 定义了一系列全局变量，用于记录社群中各类比率、群体集合、协调员、
; 核心节点信息、政府及信息传播状态、谣言及声明统计等
; ========================================================================
globals [
  pros-ratio             ; 正面意见者的比例（支持者比例）
  cons-ratio             ; 负面意见者的比例（反对者比例）
  silent-ratio           ; 沉默者比例（中立或未表态的个体比例）
  pros                   ; 存储正面意见者个体集合
  cons                   ; 存储负面意见者个体集合
  silents                ; 存储沉默者个体集合
  coordinators           ; 存储作为协调员的个体集合（特殊角色）
  cons-list              ; 记录每个时间步反对者数量的列表（用于后续绘图及变化率计算）
  pros-list              ; 记录每个时间步支持者数量的列表
  silents-list           ; 记录每个时间步沉默者数量的列表
  current-core           ; 当前的 k-core 核心值，用于意见领袖划分时动态更新
  max-num-core-turtles   ; 最大的核心节点个数（未在后续代码中直接使用，可用于限制核心规模）
  kcorelist              ; 记录采用 k-core 分解后选出的意见领袖集合（真实个体而非名字）
  is-core-matched-flag?  ; 标记当前轮 k-core 筛选是否产生了新的核心匹配（布尔值）
  run-flag?              ; 控制核心筛选轮次的开关，决定循环是否继续
  rumors                 ; 存放环境中所有谣言的 patch 集合，pcolor = 15 代表谣言
  declaration            ; 存放政府声明的 patch 集合，pcolor = 105 代表声明
  dead-rumors            ; 记录死亡谣言总数量
  dead-rumors-types      ; 记录死亡谣言的种类数（依据谣言 ID 标识去重后计算）
  listy                  ; 辅助列表，用于存储谣言种类的ID，去重统计死亡谣言类型
]

; ========================================================================
; 定义智能体（turtles）的自有变量
; ------------------------------------------------------------------------
; 每个 turtle（个体）将保存以下信息：
;   - opinion：个体的意见值（风险感知或者立场的数值表示）
;   - marked?：标记状态，用于区分是否是协调员或者已标记的特殊个体
;   - degree：网络中相邻连接个体的数量
;   - abs-y：个体纵向绝对坐标，可能用于描述社交影响距离或者其他作用
;   - heritage：用于记录个体在k-core分解过程中累积的“传承”值
;   - die??：标识个体是否在核心分解过程中被判定为“死亡”（即退出核心）
;   - fake-dead?：作为中间状态标记，标记个体是否已被核心筛选判定为“假死亡”
;   - infected-by-rumors?：是否受到了谣言的影响
;   - infected-by-declarations?：是否受到了声明的影响
;   - direct?：标记个体是否为初始直接利益相关者（直接参与事件）
;   - whom：用于记录该个体在某个队列中的位置（可能用于绘图或排序时确定横坐标）
; ========================================================================
turtles-own [
  opinion
  marked?
  degree
  abs-y
  heritage
  die??
  fake-dead?
  infected-by-rumors?
  infected-by-declarations?
  direct?
  whom
]

; ========================================================================
; 定义 Patch（环境网格）拥有的变量
; ------------------------------------------------------------------------
; 每个 patch 保存的信息包括：
;   - convincing?：表示 patch 所代表的信息（或谣言）的说服力
;   - dconvincing?：与声明相关的说服力（辟谣过程中使用）
;   - name：用于标识谣言或声明的名称（随机生成）
;   - dname：声明的名称（备用，与 name 类似）
;   - r-pofeedback & r-nefeedback：分别记录谣言收到的正面和负面反馈
;   - d-pofeedback & d-nefeedback：记录声明收到的正面及负面反馈
;   - times-viewed：记录谣言被浏览的次数
;   - dtimes-viewed：记录声明被浏览的次数
;   - generation：谣言的代际数，用以反映从原始谣言的传播层级
;   - dgeneration：声明的代际数（辟谣声明在传播过程中的变化）
;   - id-flag：用于标记某条谣言/声明的状态（如是否已扩散或作废）
;   - original?：布尔变量，记录该 patch 中信息是否为原始消息
;   - id-flag?：辅助判定标记，和 id-flag 共同作用于信息更新过程中
;   - identity-list：用于记录谣言传播链中的节点标识（列表）
;   - ppx：用于后续计算中的中间变量（可代表额外属性）
; ========================================================================
patches-own [
  convincing?
  dconvincing?
  name
  dname
  r-pofeedback
  r-nefeedback
  d-pofeedback
  d-nefeedback
  times-viewed
  dtimes-viewed
  generation
  dgeneration
  id-flag
  original?
  id-flag?
  identity-list
  ppx
]

; ========================================================================
; 程序入口：setup 过程
; ------------------------------------------------------------------------
; 1. 清空所有环境内容
; 2. 创建指定数量的居民（turtles），设定其初始属性（形状、位置、初始状态、死亡标记等）
; 3. 对每个居民调用 build-up-initial-socialnetwork 建立初始社交网络
; 4. 调用 opinion-divergence 过程，使部分个体初始意见出现随机分化，并根据沉默阈值上色区分
; 5. 根据各自 opinion 值，分别将个体分为反对者（cons）、支持者（pros）和沉默者（silents）
; 6. 初始化用于记录群体变化的列表（cons-list、pros-list、silents-list），重复两次保证不为空
; 7. 初始化政府公信力、谣言及声明相关状态、死亡谣言计数等
; 8. 对所有 patch 初始化其身份列表、标记、反馈值等
; 9. 将所有颜色为 15（红色）的 patch 归为谣言集合
; 10. 最后重置时钟，准备进入主循环
; ========================================================================
to setup
  ca  ; 清除所有对象和变量

  ; 创建居民个体（turtles），数量为 num-of-residents
  crt num-of-residents [
    set direct? true                 ; 初始时均为直接知晓事件的相关者
    set size 2                       ; 个体大小设为 2
    set shape "person"               ; 个体形状为 "person"
    set abs-y 0                      ; 初始绝对 y 坐标为 0（备用变量）
    setxy random-xcor * 0.9 random-ycor * 0.9  ; 随机分布在环境中，乘以0.9避免出界
    set fake-dead? false              ; 初始化假死亡标记为 false
    set die?? false                  ; 初始化死亡标记为 false
    build-up-initial-socialnetwork  ; 建立该个体的初始社交网络
  ]

  opinion-divergence  ; 调用意见分化过程，随机生成部分居民的意见并标记

  ; 根据 opinion 值和沉默阈值 silent-inclination，将个体分群：
  set cons turtles with [opinion < -1 * silent-inclination and marked? != 2]
  set pros turtles with [opinion > silent-inclination and marked? != 2]
  set silents turtles with [opinion <= silent-inclination and opinion >= -1 * silent-inclination and marked? != 2]

  ; 初始化记录各群体数量的列表（保证初始不为空）
  set cons-list [ ]
  set government-credibility 0.7   ; 设置初始政府公信力为 0.7
  set pros-list [ ]
  set silents-list [ ]
  set current-core 1               ; 初始 core 值设为 1，用于后续 k-core 分解
  set kcorelist [ ]
  set listy [ ]
  set dead-rumors 0                ; 初始化死亡谣言计数
  set dead-rumors-types 0          ; 初始化死亡谣言种类计数

  ; 对所有 patch 初始化部分变量：
  ask patches [
    set identity-list []           ; 空列表，用于记录谣言传播过程中传递的身份信息
    set id-flag 3                  ; 初始 id-flag 值设为 3（具体数值含义依据后续逻辑）
    set id-flag? 3                 ; 同时设置辅助 id-flag?
    set original? false            ; 初始状态非原始信息
    set r-pofeedback 0             ; 重置谣言正反馈
    set r-nefeedback 0             ; 重置谣言负反馈
    set d-pofeedback 0             ; 重置声明正反馈
    set d-nefeedback 0             ; 重置声明负反馈
  ]

  ; 重复两次将初始反对者、支持者和沉默者的数量记录进各自列表中
  repeat 2 [
    set cons-list fput (count cons) cons-list
    set pros-list fput (count pros) pros-list
    set silents-list fput (count silents) silents-list
  ]

  ; 将所有颜色为 15 的 patch 视为谣言
  set rumors patches with [pcolor = 15]

  reset-ticks  ; 重置仿真时钟
end

; ========================================================================
; 建立初始社交网络：build-up-initial-socialnetwork
; ------------------------------------------------------------------------
; 为每个居民建立其初步的社交网络关系：
; 1. 根据 socializing-scale 和居民总数确定目标连接数（num-links）
; 2. 当网络中链接数量不足时，随机选择一只个体，与其最邻近未建立连接的其他个体形成链接
; 3. 重复进行自动布局（layout-spring），模拟人际关系的弹性连接
; ========================================================================
to build-up-initial-socialnetwork
  ; 计算目标链接数：根据社交尺度和居民总数控制网络的复杂程度
  let num-links (socializing-scale * num-of-residents) / 2

  ; 当链接数量不足目标值时，循环创建链接
  while [count links < num-links] [
    ask one-of turtles [
      ; 找到与自己未建立连接且距离最近的邻居
      let close-neighbours (min-one-of (other turtles with [not link-neighbor? myself]) [distance myself])
      ;; 仅针对非自身且尚未与自身连通的个体进行链接
      if close-neighbours != nobody [
        create-link-with close-neighbours  ; 与该最邻近个体建立社交连接
      ]
    ]
  ]
  ; 重复 5 次调用 layout-spring 使网络自动布局，参数中 0.8 表示弹性系数，
  ; social-closeness 和 social-repulsion 分别代表社交距离趋向和排斥作用
  repeat 5 [
    layout-spring turtles links 0.8 social-closeness social-repulsion
  ]
end

; ========================================================================
; 意见分化过程：opinion-divergence
; ------------------------------------------------------------------------
; 用于使一部分个体随机生成意见值（范围内数值），以模拟事件中意见的多样化，
; 并根据生成的 opinion 值对个体进行颜色区分：
; 1. 随机选择一定比例（(1 - initial-protest-size)）的个体，将它们的 opinion 设为 0~100间的随机数，
;    同时将 marked? 标记设为 1，并根据是否超过 silent-inclination 上色（105代表正面，灰色代表中性）
; 2. 对剩余未标记个体，若 opinion 为 0，则重新赋予 -101到0之间随机值，并按条件上色，
;    低于 -silent-inclination的个体用颜色15显示，其他为灰色
; ========================================================================
to opinion-divergence
  ; 对于一部分个体（比例 (1 - initial-protest-size)），设置随机正面意见
  ask n-of ((1 - initial-protest-size) * num-of-residents) turtles [
    set opinion random 101      ; 随机生成 0~100 之间的数（正面偏向，视情景设定意义）
    set marked? 1               ; 标记该个体已被赋予初始意见
    if opinion > 1 * silent-inclination [ set color 105 ]  ; 超过沉默阈值，标记为正面（颜色105）
    if opinion >= 0 and opinion <= 1 * silent-inclination [ set color grey ] ; 否则中性
  ]
  ; 对于未被标记的个体（可能意见为0），赋予负面意见
  ask turtles [
    if opinion = 0 and marked? != 1 [
      set opinion random -101   ; 随机生成一个负面意见（-101 到 0）
      if opinion = 0 [ set opinion random -101 ] ; 防止为 0 的情况
      ifelse opinion < -1 * silent-inclination [
        set color 15            ; 低于沉默阈值，标记为负面（颜色15）
      ] [
        set color grey          ; 否则标记为中性
      ]
    ]
  ]
end

; ========================================================================
; 主循环过程：go
; ------------------------------------------------------------------------
; 每个 tick 内依次执行下列步骤：
; 1. 重新划分群体：更新反对者（cons）、支持者（pros）、沉默者（silents）的集合
; 2. 根据群体属性设置对应颜色：反对者（颜色15）、支持者（颜色105）、沉默者（灰色）
; 3. 找出标记为协调员的个体（marked? = 2），更新谣言（pcolor = 15）和声明（pcolor = 105）的 patch 集合
; 4. 设置终止条件：例如当反对者数量过少或几乎覆盖全部个体时停止模拟
; 5. 调用 influence-newcomers 处理新加入个体的影响更新（按照BA模型扩展网络）
; 6. 每个 turtle 移动一步（fd 1）并调用 communicate-opinions 过程进行舆论传播
; 7. 如果开启协调员机制（两种模式），则协调员会定位到最激烈的反对者或意见领袖，
;    并执行 be-persuasive 以改变其意见
; 8. 当 tick 达到一定值后，如果开启声明机制（make-declaration? 为 true），
;    则调用 if-mouse-down、generate-auto、be-affected-by-declarations&show-attitudes-to-declarations、
;    spreading-declarations 和 when-to-delete 对政府声明的生成、影响和消解进行处理
; 9. 如果启动谣言传播机制（hatch-rumors? 为 true），则依次调用 breeding-rumors、
;    be-affected-by-rumors&show-attitudes-to-rumors、spreading-rumors、when-to-dieout 处理谣言
; 10. 每个时间步更新各类群体数量的列表供后续绘图使用
; 11. 将所有链接隐藏（设置 hidden? 为 true），最后 tick 前进一格
; ========================================================================
to go
  ; 重新按当前 opinion 和标记状态更新各群体
  set cons turtles with [opinion < -1 * silent-inclination and marked? != 2]
  set pros turtles with [opinion > silent-inclination and marked? != 2]
  set silents turtles with [opinion <= silent-inclination and opinion >= -1 * silent-inclination and marked? != 2]

  ; 根据群体分配颜色
  ask cons [ set color 15 ]
  ask pros [ set color 105 ]
  ask silents [ set color grey ]

  ; 定位协调员个体（marked? 等于 2）
  set coordinators turtles with [marked? = 2]

  ; 更新谣言集合：所有颜色为15的patch
  set rumors patches with [pcolor = 15]
  ; 更新声明集合：所有颜色为105的patch
  set declaration patches with [pcolor = 105]

  ; 终止条件判断：
  ; 如果反对者的数量少于（整体非协调员个体的 30% 并且直接反对者数量少于 0.3*num-of-residents），则停止运行
  if (count cons < 0.3 * count turtles with [marked? != 2] and count cons with [direct?] < 0.3 * num-of-residents) [ stop ]
  ; 如果反对者数量超过 95% 的总个体，则停止运行
  if count cons >= 0.95 * count turtles [ stop ]
  ; 如果支持者和沉默者均为 0，则停止运行
  if count pros = 0 and count silents = 0 [ stop ]

  influence-newcomers   ; 调用新来个体的影响更新过程

  ; 每个 turtle 前进一步，并随机转向后传播意见
  ask turtles [
    fd 1
    rt random 360
    communicate-opinions  ; 传播意见过程
  ]

  ; ------------------------------------------------------------------------
  ; 协调员机制：两种工作方式
  ; 方式1：协调员寻找意见最激烈的反对者进行干预
  ; 方式2：协调员寻找意见领袖（基于k-core分解产生的核心节点），意见领袖可能随着新 turtle 加入而不断变化
  ; ------------------------------------------------------------------------
  if go-to-the-most-aggressive-protestors [
    ask coordinators [
      move-to-the-most-aggresive-protests  ; 定位到激进反对者处
      be-persuasive                       ; 进行劝说工作
    ]
  ]

  if go-to-influencer [
    find-the-influencer  ; 执行意见领袖寻找过程
    ask coordinators [
      move-to-the-influencer  ; 移动到意见领袖位置
      be-persuasive           ; 进行劝说工作
    ]
  ]

  ; ------------------------------------------------------------------------
  ; 政府声明（辟谣）处理：当 tick 大于等于 360 且满足 make-declaration? 条件后
  ; ------------------------------------------------------------------------
  if ticks >= 360 [
    if make-declaration? [
      if-mouse-down  ; 处理鼠标点击引发的声明（蓝色patch）
      generate-auto  ; 自动生成声明（当谣言数量大于声明数量时）
      be-affected-by-declarations&show-attitudes-to-declarations  ; 个体受声明影响，同时记录态度
      spreading-declarations   ; 声明的传播过程
      when-to-delete           ; 删除影响力降低的声明
    ]
  ]

  ; ------------------------------------------------------------------------
  ; 谣言传播处理
  ; ------------------------------------------------------------------------
  if hatch-rumors? [
    breeding-rumors   ; 产生新的谣言（由反对者主动生成，在特定条件下进行）
    be-affected-by-rumors&show-attitudes-to-rumors  ; 个体受谣言影响，同时记录反馈
    spreading-rumors  ; 谣言的传播过程（包括转发与算法推荐机制）
    when-to-dieout    ; 清除“死亡”的谣言，更新政府公信力
  ]

  ; 每个时间步更新各群体数量记录到列表中（供绘图计算导数）
  set cons-list fput (count cons) cons-list
  set pros-list fput (count pros) pros-list
  set silents-list fput (count silents) silents-list

  ; 隐藏所有链接（将其属性 hidden? 设为 true，可能用于美观）
  ask links [ set hidden? true ]

  tick  ; 仿真时钟前进一格
end

; ========================================================================
; 当谣言失去影响力时将其“死亡”：when-to-dieout
; ------------------------------------------------------------------------
; 此过程主要：
; 1. 对环境中所有谣言 patch（pcolor = 15 或 id-flag=0）的判断
; 2. 当谣言已达到失效条件（说服力低或者传播链失效）则进行标记，改为橙色（pcolor = 25），
;    并更新死亡谣言计数与死亡种类（通过 identity-list 和辅助列表 checked, listy 计算）
; 3. 同时根据死亡的谣言数量反馈给政府公信力做调整
; ========================================================================
to when-to-dieout
  let checked [ ]
  let checked2 0
  ; 对于存在并说服力 >= 0 的谣言 patch：
  ask rumors with [convincing? >= 0] [
    set pcolor 25             ; 修改颜色为 25，代表死亡谣言
    set id-flag 3
    set dead-rumors dead-rumors + 1  ; 增加死亡谣言计数
    set checked2 checked2 + 1
    ; 如果传播链中只有单一身份标识，则更新死亡谣言种类
    if length identity-list = 1 [
      if not member? (item 0 identity-list) [identity-list] of other rumors with [name = [name] of myself] [
        set checked lput (item 0 identity-list) checked
        set checked remove-duplicates checked
        set listy lput (item 0 identity-list) listy
        set listy remove-duplicates listy
        set dead-rumors-types (length listy)
      ]
    ]
    set identity-list []   ; 清空身份传播链
    set original? false
  ]

  ; 对于 id-flag = 0 的谣言 patch：
  ask rumors with [id-flag = 0] [
    set original? false
    ; 查看其他同名且代际更高的谣言
    ask other rumors with [name = [name] of myself and generation > [generation] of myself] [
      foreach [identity-list] of myself [ x ->
        if (member? x identity-list) [
          set pcolor 25
          set id-flag 3
          set original? false
          set dead-rumors dead-rumors + 1
          if length identity-list = 1 [
            set checked lput (item 0 identity-list) checked
            set checked remove-duplicates checked
            set listy (lput (item 0 identity-list) listy)
            set listy remove-duplicates listy
            set dead-rumors-types (length listy)
          ]
          set identity-list []
        ]
      ]
    ]
    set pcolor 25
    set id-flag 3
    set checked2 checked2 + 1
    set dead-rumors dead-rumors + 1
    if length identity-list = 1 [
      set checked lput (item 0 identity-list) checked
      set checked remove-duplicates checked
      set listy lput (item 0 identity-list) listy
      set listy remove-duplicates listy
      set dead-rumors-types (length listy)
    ]
    set identity-list []
  ]
  ; 根据死亡谣言的数目反馈增加政府公信力
  set government-credibility government-credibility + checked2 * 0.5 / 1000 + length checked * 0.5 / (1 + length checked + count patches with [original?])
end

; ========================================================================
; 谣言生产与传播：breeding-rumors
; ------------------------------------------------------------------------
; 对于处于反对者群体（cons）且直接传播模式（direct?）的个体：
; 1. 如果该个体没有与邻居建立谣言链接（即周围无 pcolor = 15）；
; 2. 且其 opinion 低于区域平均 opinion 值乘以政府公信力；
; 3. 且附近没有声明（in-radius 2 patch 无 pcolor = 105）；
; 那么，以一定的随机概率（其立方函数降低政府公信力越高时谣言生成的可能性）生成谣言
; 生成的谣言会在所在 patch 上被标记为 pcolor = 15，并初始化其一些属性（如身份列表、名称、代际数、说服力等）
; ========================================================================
to breeding-rumors
  ;; 遍历所有反对者 cons 且 direct? = true 的个体
  ask cons with [direct?] [
    ;; 条件判断一：该 turtle 周围未建立任何谣言链接
    ;;    count link-neighbors with [color = 15] = 0
    ;; 条件判断二：自身 opinion < 平均反对者 opinion × 政府公信力
    ;; 条件判断三：patch 半径 vision-information = 2 内无声明（color = 105）
    if ( count link-neighbors with [color = 15] = 0
         and
         opinion < ( mean [opinion] of cons ) * government-credibility
         and
         count declaration in-radius 2 = 0
       ) [
      ;; 在上述条件均满足时，以 (random-float 1)^3 > government-credibility 的概率造谣
      ;; 这里将 random-float 1 提升到 3 次方，目的是使高公信力时概率更低
      if ( (random-float 1) ^ 3 > government-credibility ) [
        ;; 在当前 turtle 所在 patch 上生成新谣言
        ask patch-here [
          set pcolor 15                   ; 设成红色，代表谣言出现
          set id-flag 1                   ; 标志为新生成的谣言
          ;; 将自身 (turtle) 的位置坐标作为初始化 identity-list
          set identity-list lput ([list pxcor pycor] of self) identity-list
          set name random-float 100       ; 随机生成一个 0–100 的 ID 作为谣言标识
          set generation 1                ; 第一代谣言
          set original? true              ; 标记为原始谣言
          set times-viewed 0              ; 初始化浏览次数
          ;; 说服力引用造谣者本人的 opinion
          set convincing? [opinion] of myself
        ]
      ]
    ]
  ]
end


; ========================================================================
; 个体受谣言影响与态度反馈展示：be-affected-by-rumors&show-attitudes-to-rumors
; ------------------------------------------------------------------------
; 对于未被协调员标记的个体（marked? != 2）：
; 1. 如果个体所在 patch 为谣言（pcolor = 15），则增加该 patch 上的浏览次数
; 2. 根据随机概率（与政府公信力相关）和个体 opinion 的正负（分别对应两种影响规则）：
;    - 若 opinion 为负，则 opinion 进一步下降，同时 patch 的说服力也同步下降，并记录正向反馈
;    - 若 opinion 为正，则 opinion 受到一定的负面调整，同时 patch 的说服力增加或减小，记录负反馈
; 3. 最后个体转向 90 度并前进 3 步，模拟漫游
; ========================================================================
to be-affected-by-rumors&show-attitudes-to-rumors
  ;; 遍历所有非协调员个体
  ask turtles with [marked? != 2] [
    ;; 若所在 patch 为谣言（pcolor=15）
    if [pcolor] of patch-here = 15 [
      ;; 累加该 patch 的浏览次数
      ask patch-here [
        set times-viewed times-viewed + 1
      ]
      ;; 若随机浮点大于政府公信力，允许该谣言影响 opinion
      if random-float 1 > government-credibility [
        ifelse opinion < 0 [
          ;; —— 对于持反对态度的个体（opinion<0）：
          ;;    opinion_new = opinion_old - 1 × |convincing?|^(1/6)
          ;;    且如果新 opinion 依旧超出沉默阈值，patch 的 convincing? 和 r-pofeedback 要同步修改
          set opinion
            opinion
            - 1 * ( abs [convincing?] of patch-here ) ^ (1 / 6)
          if abs opinion > silent-inclination [
            ask patch-here [
              set convincing? convincing?
                                - ( abs [opinion] of myself ) ^ (1 / 6)
              set r-pofeedback r-pofeedback
                               + ( abs [opinion] of myself ) ^ (1 / 6)
            ]
          ]
        ] [
          ;; —— 对于持正面态度或中立的个体（opinion ≥0）：
          ;;    仅在小概率下（random-float 100 < average-chance-of-being-affected）
          ;;    会使 opinion 轻微下调，并对 patch 的 convincing? 和 r-nefeedback 作记录
          if random-float 100 < average-chance-of-being-affected [
            set opinion
              opinion
              - 1 * ( abs [convincing?] of patch-here ) ^ (1 / 7)
            if opinion > silent-inclination [
              ask patch-here [
                set convincing? convincing?
                                  + ( abs [opinion] of myself ) ^ (1 / 6)
                set r-nefeedback r-nefeedback
                                 + (-1) * ( abs [opinion] of myself ) ^ (1 / 6)
              ]
            ]
          ]
        ]
      ]
    ]
    ;; 小幅漫游：转向 90°，前进 3 步，继续模拟领导者外的随机漫游
    rt 90
    fd 3
  ]
end


; ========================================================================
; 谣言传播过程：spreading-rumors
; ------------------------------------------------------------------------
; 分为两种分发机制：
; 1. 由个体主动转发：反对者在所在 patch 为谣言时，在前进 3 步后，
;    检查前方 patch（patch-ahead 2）是否不为谣言或声明状态，若满足条件则进行谣言传播，
;    此过程中会对传播后的谣言设置新的 identity-list、说服力、代际增加等逻辑
; 2. 算法推荐：检查谣言浏览次数满足一定周期（times-viewed mod 500 = 0）且累计负或正反馈大于0，
;    然后从激进反对者中抽取一部分目标个体，对其所在 patch进行同样的谣言传播操作
; ========================================================================
to spreading-rumors
  ask cons [
    if [pcolor] of patch-here = 15 [
      let ance-generation [generation] of patch-here
      let peritage [convincing?] of patch-here
      let family-name [name] of patch-here
      let listx [identity-list] of patch-here
      ;; 以 (random-float 1)^2 > government-credibility 为概率条件，决定是否转发
      if (random-float 1) ^ 2 > government-credibility [
        fd 3                                        ; 向前移动3格
        ask patch-ahead 2 [                        ; 查看前方第2格的 patch
          if pcolor != 15 [                        ; 如果不是谣言
            ifelse pcolor != 105 [                 ; 且不是声明
               ; —— 情况1：非声明非谣言 patch
              set pcolor 15
              set id-flag 1
              set times-viewed 0
              set name family-name
              set generation ance-generation + 1
              let dice1 random-float 100
              let dice2 random-float (100 - dice1)
              let dice random-float 100
              ifelse dice <= dice1 [
                ; —— 分支 A：完全继承
                set identity-list listx
                set convincing? peritage
              ] [
                ifelse dice > (dice1 + dice2) [
                   ; —— 分支 C：全新重构
                  set convincing? [opinion] of myself
                  set identity-list lput ([list pxcor pycor] of self) identity-list
                  set original? true
                ] [
                   ; —— 分支 C：全新重构
                  set identity-list lput ([list pxcor pycor] of self) listx
                  set convincing? 0.5 * [opinion] of myself + 0.5 * peritage
                  set ppx 100
                ]
              ]
            ] [ ; —— 情况2：如果遇到声明 patch，调用 to-compare 进行说服力比较
              set id-flag 1
              to-compare  ; 比较与调整信息属性的子过程
            ]
          ]
        ]
      ]
    ]
  ]
   ;; —— 算法推荐机制
  ask rumors [
    ;; 每当 times-viewed 恰好是500的整数倍，且累积反馈>0时触发
    if times-viewed mod 500 = 0 [
      if (r-nefeedback + r-pofeedback) > 0 [
        let peritage convincing?
        let ance-generation generation
        let family-name name
        let listx identity-list
        ;; 选取当前最“激进”反对者 top10% 作为推荐对象
        let aggresive-list sort-on [opinion] turtles with [marked? != 2]
        let redline 0.1 * (count turtles with [marked? != 2])
        let x-list sublist aggresive-list 0 redline
        let x one-of x-list
        ask x [
          ask patch-here [
            if pcolor != 15 [
              ifelse pcolor != 105 [
                set pcolor 15
                set id-flag 1
                set times-viewed 0
                set name family-name
                set generation ance-generation
                set identity-list listx
                set convincing? peritage
              ] [
                set id-flag 1
                to-compare
              ]
            ]
          ]
        ]
      ]
    ]
  ]
end

; ========================================================================
; to-compare 子过程
; ------------------------------------------------------------------------
; 对比当前信息（谣言或声明）的说服力与 dconvincing?（辟谣声明相关说服力），
; 根据二者绝对值大小决定是否更新标记及颜色
; ========================================================================
to to-compare
  ; 如果该 patch 的信息为“待比较”状态（id-flag = 1）且未曾比较过（id-flag? = 1），才执行接下来的逻辑
  if id-flag = 1 and id-flag? = 1 [
    ; 比较当前说服力绝对值与声明说服力绝对值
    ifelse abs convincing? > abs dconvincing? [
      set id-flag? 3
      set pcolor 15
      set convincing? convincing? + dconvincing?
    ]
    [
      set pcolor 15
      set id-flag 0
    ]
  ]
end

; ========================================================================
; 意见传播过程：communicate-opinions
; ------------------------------------------------------------------------
; 每个 turtle 会按照与邻居的链接关系传递意见信息：
; 1. 首先处理链接邻居中 opinion > 0 的个体：
;    根据距离，随机概率决定是否传递意见，若传递则：
;      - 如果自身 opinion 非常负，则降低 opinion 值（传递反对观点）
;      - 如果 opinion 较正，则增加 opinion 值（传递支持观点）
; 2. 再处理 opinion < 0 的邻居，逻辑类似；
; 3. 对于处于沉默区间的个体，既不传播也不发生变化
; ========================================================================
to communicate-opinions
  ; 处理支持性邻居（opinion > 0）的传播过程
  let pneighbor link-neighbors with [opinion > 0]
  ; pneighbor 是与当前 turtle 通过 link 相连且 opinion 为正的所有邻居列表
  ask pneighbor [
    ; 对于每一个支持性邻居，根据距离决定是否触达
    ; 100 / (distance myself + 1) 保证距离越近传播概率越高
    if random-float 100 <= 100 / (distance myself + 1) [
      ; --- 当传播者自身 opinion 非常负（强烈反对）时，向支持者传播反对观点 ---
      if [opinion] of myself < -1 * silent-inclination [
        if random-float 100 <= average-chance-of-being-affected [
          set opinion opinion - 1 * (abs [opinion] of myself) ^ (1 / 7) / (distance myself + 1)
        ]
      ]
      ; --- 当传播者自身 opinion 为正（支持者）时，向他人传播支持观点 ---
      if [opinion] of myself > silent-inclination [
        set opinion opinion + 1 * [opinion] of myself ^ (1 / 6) / (distance myself + 1)
      ]
      ; --- 当传播者处于“沉默区间”时，不改变对方 opinion ---
      if [opinion] of myself <= silent-inclination and [opinion] of myself >= -1 * silent-inclination [
        set opinion opinion + 0
      ]
    ]
  ]
  ; 处理反对性邻居（opinion < 0）的传播过程
  let cneighbors link-neighbors with [opinion < 0]
  ask cneighbors [
    if random-float 100 <= 100 / (distance myself + 1) [
      ; --- 强烈反对者自身 opinion < -silent-inclination 时，传播反对观点 ---
      if [opinion] of myself < -1 * silent-inclination [
        set opinion opinion - 1 * (abs [opinion] of myself) ^ (1 / 6) / (distance myself + 1)
      ]
      ; --- 当反对者传播给支持者时，也可能影响支持者 opinion ---
      if [opinion] of myself > silent-inclination [
        if random-float 100 <= average-chance-of-being-affected [
          set opinion opinion + 1 * ([opinion] of myself) ^ (1 / 7) / (distance myself + 1)
        ]
      ]
      ; --- 对于处于沉默区间的对方，不做改动 ---
      if [opinion] of myself <= silent-inclination and [opinion] of myself >= -1 * silent-inclination [
        set opinion opinion + 0
      ]
    ]
  ]
end

; ========================================================================
; 删除低影响力声明：when-to-delete
; ------------------------------------------------------------------------
; 遍历所有声明（patch 的 pcolor 为 105），当声明的 dconvincing? 小于等于 0 时：
; 1. 将声明颜色设为 135（可能代表死亡或失效）
; 2. 更新 id-flag?，同时略微降低政府公信力（每次减少 1/1000）
; ========================================================================
to when-to-delete
  ; 针对每一个具有声明标识（pcolor = 105）的 patch
  ask declaration with [ dconvincing? <= 0 ] [
    set pcolor 135                 ; 将颜色设为 135（粉色），表示声明失效/死亡
    set id-flag? 3                 ; 辅助标记置为 3，表示此声明已不可再传播
    ; 政府公信力每次减少 0.001（1/1000）
    set government-credibility government-credibility - 1 / 1000
  ]
end

; ========================================================================
; 鼠标点击触发声明（政府声明）：if-mouse-down
; ------------------------------------------------------------------------
; 当用户按下鼠标时：
; 1. 所有 turtle 检查鼠标所在位置的 patch
; 2. 将该 patch 的颜色设为 105（蓝色，代表政府声明）
; 3. 重置声明浏览次数、标记 id-flag? 和设置 dconvincing?（依据政府公信力调整）
; ========================================================================
to if-mouse-down
  ask turtles [
    ; 检查当前 turtle 是否检测到鼠标按下事件
    if mouse-down? [
      ; 在鼠标所在 patch 上创建声明
      ask patch mouse-xcor mouse-ycor [
        set pcolor 105               ; 设为蓝色，表示新声明
        set dtimes-viewed 0          ; 重置声明浏览次数计数器
        set id-flag? 1               ; 辅助标记置为 1，表示可比较/传播
        set dconvincing? 100 * government-credibility
        ; 声明的初始说服力 = 100 × 当时政府公信力
      ]
    ]
  ]
end

; ========================================================================
; 自动生成声明：generate-auto
; ------------------------------------------------------------------------
; 当谣言数量大于声明数量时，从谣言中选择若干 patch（基于 count 差值）生成声明：
; 1. 从谣言 patch 中选取拥有最多 turtle（即关注度较高）的 patch，若其颜色不为 105 且不为 15，
;    则将其颜色设定为 105，同时初始化相关属性（id-flag?、dtimes-viewed、dconvincing?）
; ========================================================================
to generate-auto
  ; 如果当前谣言 patch 数量大于声明 patch 数量
  if count rumors > count declaration [
    ; 选择关注度最高的 (count rumors - count declaration) 个 patch
    ask max-n-of (count rumors - count declaration) patches [
      count turtles-on self
    ] [
      ; 如果该 patch 不是已有声明（pcolor≠105）
      if pcolor != 105 [
        ifelse pcolor != 15 [
          ; 若也不是谣言，则直接生成新声明
          set pcolor 105
          set id-flag? 1
          set dtimes-viewed 0
          set dconvincing? 100 * government-credibility
        ] [
          ; 若是谣言，则将其转换为声明，同时比较说服力
          set id-flag? 1
          to-compare
        ]
      ]
    ]
  ]
end

; ========================================================================
; 个体受政府声明影响与态度反馈展示：be-affected-by-declarations&show-attitudes-to-declarations
; ------------------------------------------------------------------------
; 对于非协调员的 turtle，当所在 patch 为声明（pcolor = 105）：
; 1. patch 中累计浏览次数 dtimes-viewed 增加
; 2. 根据随机概率（与政府公信力相关）以及个体 opinion 正负分别进行正负调整，
;    同时更新 patch 中 dconvincing?（反应政府声明说服力变化）并记录正负反馈
; 3. turtle 随后转向 90 度并前进 3 步
; ========================================================================
to be-affected-by-declarations&show-attitudes-to-declarations
  ask turtles with [ marked? != 2 ] [
    ; 仅对非协调员个体生效
    if [ pcolor ] of patch-here = 105 [
      ; 累加该声明被浏览的次数
      ask patch-here [
        set dtimes-viewed dtimes-viewed + 1
      ]
      ; 按概率决定个体是否被声明影响（概率 = government-credibility）
      if random-float 1 <= government-credibility [
        ifelse opinion < 0 [
          ; 对反对者进行正面劝导
          if random-float 100 < average-chance-of-being-affected [
            ; delta = +1 * |dconvincing?|^(1/7)
            set opinion opinion + 1 * ( abs [ dconvincing? ] of patch-here ) ^ ( 1 / 7 )
            if abs opinion > silent-inclination [
              ; 当 opinion 绝对值超阈时，在 patch 上记录负反馈
              ask patch-here [
                set dconvincing? dconvincing? - ( abs [ opinion ] of myself ) ^ ( 1 / 6 )
                set d-nefeedback d-nefeedback + ( -1 ) * ( abs [ opinion ] of myself ) ^ ( 1 / 6 )
              ]
            ]
          ]
        ] [
          ; 对支持者也增强其支持力度
          set opinion opinion + 1 * ( abs [ dconvincing? ] of patch-here ) ^ ( 1 / 6 )
          if abs opinion > silent-inclination [
            ask patch-here [
              set dconvincing? dconvincing? + ( abs [ opinion ] of myself ) ^ ( 1 / 6 )
              set d-pofeedback d-pofeedback + ( abs [ opinion ] of myself ) ^ ( 1 / 6 )
            ]
          ]
        ]
      ]
    ]
    rt 90        ; 转向90度，模拟个体运动方向变化
    fd 3         ; 向前移动3步
  ]
end

; ========================================================================
; 声明的传播过程：spreading-declarations
; ------------------------------------------------------------------------
; 1. 由支持者（pros）传播：位于声明 patch 的个体，
;    根据政府公信力判定进一步传播，将前方 patch（patch-ahead 2）改色为 105，并初始化声明属性
; 2. 此外，遍历所有声明 patch，若浏览次数 dtimes-viewed 是 500 的整数倍，
;    且负面反馈与正面反馈之和大于 0，则在部分个体中选择进行二次传播
; ========================================================================
to spreading-declarations
  ; --- 支持者主动转发 ---
  ask pros [
    if [ pcolor ] of patch-here = 105 [
      let peritage [ dconvincing? ] of patch-here
      ; 以政府公信力为概率门槛，可能连续两次传播
      if random-float 1 < government-credibility [
        if random-float 1 < government-credibility [
          ask patch-ahead 2 [
            if pcolor != 105 [
              ifelse pcolor != 15 [
                set pcolor 105
                set id-flag? 1
                set dtimes-viewed 0
                set dconvincing? peritage
              ] [
                set id-flag? 1
                to-compare
              ]
            ]
          ]
        ]
      ]
    ]
  ]
  ; --- 算法推荐机制 ---
  ask declaration [
    ; 每当浏览次数达到500的倍数时触发
    if dtimes-viewed mod 500 = 0 [
      if d-nefeedback + d-pofeedback > 0 [
        let peritage dconvincing?
        ; 按 opinion 逆序选取前10%活跃支持者
        let supporter-list sort-on [ (- opinion ) ] turtles with [ marked? != 2 ]
        let redline 0.1 * ( count turtles with [ marked? != 2 ] )
        let x-list sublist supporter-list 0 redline
        let x one-of x-list
        ask x [
          ask patch-here [
            if pcolor != 105 [
              ifelse pcolor != 15 [
                set pcolor 105
                set id-flag? 1
                set dtimes-viewed 0
                set dconvincing? peritage
              ] [
                set id-flag? 1
                to-compare
              ]
            ]
          ]
        ]
      ]
    ]
  ]
end


; ========================================================================
; 协调员生成过程：coordinator
; ------------------------------------------------------------------------
; 1. 从所有 turtle 中筛选出协调员（marked? = 2）
; 2. 在随机选定的非当前 patch 上找出邻居数最多的 patch（thee-spot），
;    然后在其上发芽生成 5 个新的个体（sprout 5），这些个体作为政府派出的“协调员”
;    设定其颜色、形状、大小和 opinion 固定值（例如 10000，代表强烈立场或指令传递）
; ========================================================================
to coordinator
  ; 更新协调员集合：所有 marked? = 2 的 turtles
  set coordinators turtles with [ marked? = 2 ]
  ; 从非当前 patch 中随机选一个以生成坐标基点
  ask one-of other patches [
    ; 在所有 patch 中找出周围 turtle 最多的那个 patch
    let thee-spot max-one-of other patches [ count turtles-on neighbors ]
    ask thee-spot [
      ; 在该 patch 上 sprout 出 5 个新 turtle，作为政府派出的协调员
      sprout 5 [
        set color green           ; 绿色标识协调员
        set direct? false         ; 非直接利益相关者
        set marked? 2             ; 标记其为协调员
        set size 2                ; 设置大小
        set shape "person soldier" ; 设置形象
        set opinion 10000         ; 赋予极高 opinion 值，以利干预
      ]
    ]
  ]
end


; ========================================================================
; 寻找意见领袖（influencer）：find-the-influencer
; ------------------------------------------------------------------------
; 基于 k-core 分解：
; 1. 设置 run-flag? 为 true 启动循环；
; 2. 循环中判断各 turtle（未标记为 die??）的邻居数加上传承 heritage 是否小于当前核心值 current-core，
;    则认为该个体符合核心条件，将其加入 kcorelist，并标记为 fake-dead?（待“死亡”）
; 3. 将 fake-dead? 的个体设为 die?? 并更新标志位；
; 4. 如果整轮未发现新的符合条件的个体，则当前核心值加 1，并终止循环（run-flag? 设置为 false）
; ========================================================================
to find-the-influencer
  set run-flag? true               ; 启动分解循环
  while [ run-flag? ] [
    set is-core-matched-flag? false ; 本轮初始未匹配到任何节点
    ask turtles with [ die?? = false ] [
      ; 计算当前 turtle 在剩余网络中的活动度（邻居数）
      let nb count link-neighbors with [ die?? = false ]
      ; 若 nb + heritage * 0.7 ≤ current-core，说明其属于当前核心
      if nb + heritage * 0.7 <= current-core [
        set is-core-matched-flag? true
        ; 增加其邻居的 heritage 值，用以下一轮过滤
        ask link-neighbors with [ die?? = false ] [
          set heritage heritage + 1
        ]
        ; 将该 turtle 加入核心列表
        set kcorelist fput self kcorelist
        set fake-dead? true          ; 中间标记为“假死亡”
      ]
    ]
    ; 将所有 fake-dead? 的 turtle 设置为真正 die??
    ask turtles with [ fake-dead? = true ] [
      set die?? true
    ]
    ; 若本轮没有任何新匹配，提升核心阈值并结束循环
    if is-core-matched-flag? = false [
      set current-core current-core + 1
      set run-flag? false
    ]
  ]
end


; ========================================================================
; 清除协调员：clear-coordinator
; ------------------------------------------------------------------------
; 随机从标记为协调员（marked? = 2）的个体中选取指定数量（clear-n-of-coordinators）进行删除
; ========================================================================
to clear-coordinator
  ask n-of clear-n-of-coordinators turtles with [marked? = 2] [ die ]
end

; ========================================================================
; 协调员移动到意见领袖位置：move-to-the-influencer
; ------------------------------------------------------------------------
; 根据 k-core 分解的结果：
; 1. 取 kcorelist 前 10% 的个体作为“头部意见领袖”
; 2. 从中随机选取一个目标，当前调用者（协调员）将直接移动到该目标位置
; ========================================================================
to move-to-the-influencer
  let headpart 0.1 * length kcorelist
  ; 提取前 headpart 个核心节点
  let kcorelist2.0 sublist kcorelist 0 headpart
  let head one-of kcorelist2.0      ; 随机选取一名意见领袖
  move-to head                      ; 协调员移动至其位置
end

; ========================================================================
; 协调员移动到最激进反对者处：move-to-the-most-aggresive-protests
; ------------------------------------------------------------------------
; 1. 将所有非协调员按 opinion 排序，取最前 10% 内部作为目标集合；
; 2. 随机选取其中一个，协调员移动到该目标位置
; ========================================================================
to move-to-the-most-aggresive-protests
  let aggresive-list sort-on [opinion] turtles with [marked? != 2]
  let redline 0.1 * (count turtles with [marked? != 2])
  let x-list sublist aggresive-list 0 redline
  move-to one-of x-list
end

; ========================================================================
; 协调员劝说过程：be-persuasive
; ------------------------------------------------------------------------
; 协调员在当前位置查找一个个体（meet-person），若该个体属于目标群体（反对或支持）：
; 根据政府公信力的随机概率进行劝说（例如增加 opinion 值 10）
; ========================================================================
to be-persuasive
  let meet-person one-of turtles-here  ; 随机选择同一位置的一个个体
  ; 如果其为反对者
  if member? meet-person turtles with [ opinion < 0 and marked? != 2 ] [
    ; 以政府公信力为概率阈值进行劝说
    if random-float 1 <= government-credibility [
      ask meet-person [ set opinion opinion + 10 ]
    ]
  ]
  ; 如果其为支持者
  if member? meet-person turtles with [ opinion >= 0 and marked? != 2 ] [
    if random-float 1 > government-credibility [
      ask meet-person [ set opinion opinion + 10 ]
    ]
  ]
end

; ========================================================================
; 新来个体影响更新过程：influence-newcomers
; ------------------------------------------------------------------------
; 每隔 3 tick：
; 1. 每个已有个体计算其 degree（连接数），并构建一个序列 deg-seq（存储各个邻居的 who 编号）
; 2. 新创建 1 个 turtle，设定其 direct? 为 false、形状、大小和初始 opinion 为邻居意见的加权平均，
;    同时与部分选中的已有个体创建连接，新 turtle 的 opinion 根据相连个体的 opinion 进行调整
; 3. 重新调用 layout-spring 完成网络自动布局
; ========================================================================
to influence-newcomers
  if ticks mod 3 = 0 [
    let deg-seq []                  ; 清空临时邻居序列
    ask turtles [
      set degree count link-neighbors
      ; 将每个邻居的 who 编号加入 deg-seq 列表
      repeat degree [
        set deg-seq lput who deg-seq
      ]
    ]
    let new_id -1
    crt 1 [
      set direct? false
      set shape "person"
      set size 2
      set degree m                 ; m 为新连接数量
      set new_id who               ; 记录自身 who 编号
    ]
    repeat m [
      let x one-of deg-seq         ; 随机选择一个已有 turtle 的 who
      ask turtle new_id [
        create-link-with turtle x [ ; 与该 turtle 建立链接
          set color yellow          ; 设为黄色表示新连接
          set thickness 0.5
        ]
        ; 将新 turtle 的 opinion 按 1/m * 邻居 opinion 累加
        set opinion opinion + ( 1 / m ) * ( [ opinion ] of turtle x )
        set deg-seq remove x deg-seq
      ]
      layout-spring turtles links 0.8 social-closeness social-repulsion
    ]
  ]
end

; ========================================================================
; 更新绘图变量——反对者比例：update-plot-cons
; ------------------------------------------------------------------------
; 根据当前反对者数量除以总体非协调员个体数更新 pros-ratio 变量，
; 并调用 plot 显示绘图点
; ========================================================================
to update-plot-cons
  let num-cons count cons
  set cons-ratio (num-cons / (count turtles with [marked? != 2]))
  plot cons-ratio
end

; ========================================================================
; 更新绘图变量——支持者比例：update-plot-pros
; ------------------------------------------------------------------------
; 同上，针对支持者比例的更新和绘图
; ========================================================================
to update-plot-pros
  let num-pros count pros
  set pros-ratio (num-pros / (count turtles with [marked? != 2]))
  plot pros-ratio
end

; ========================================================================
; 更新绘图变量——沉默者比例：update-plot-silents
; ------------------------------------------------------------------------
; 同上，计算沉默者比例并调用绘图
; ========================================================================
to update-plot-silents
  let num-silents count silents
  set silent-ratio (num-silents / (count turtles with [marked? != 2]))
  plot silent-ratio
end

; ========================================================================
; 更新反对者变化率绘图：update-derivative-of-cons
; ------------------------------------------------------------------------
; 从 cons-list 中取前两个记录，计算差值作为导数并绘图
; ========================================================================
to update-derivative-of-cons
  let y1 first cons-list
  let y2 item 1 cons-list
  let deltay y1 - y2
  plot deltay
end

; ========================================================================
; 更新支持者变化率绘图：update-derivative-of-pros
; ------------------------------------------------------------------------
; 同上，针对 pros-list 的导数计算和绘图
; ========================================================================
to update-derivative-of-pros
  let y1 first pros-list
  let y2 item 1 pros-list
  let deltay y1 - y2
  plot deltay
end

; ========================================================================
; 更新沉默者变化率绘图：update-derivative-of-silents
; ------------------------------------------------------------------------
; 同上，针对 silents-list 的导数计算和绘图
; ========================================================================
to update-derivative-of-silents
  let y1 first silents-list
  let y2 item 1 silents-list
  let deltay y1 - y2
  plot deltay
end

; ========================================================================
; x 轴绘图更新（反对者部分）：update-fdz
; ------------------------------------------------------------------------
; 1. 根据反对者数量设置绘图 x 轴范围
; 2. 对于每个反对者，根据其在排好序列表中的位置赋值 whom（相对位置）
;    并调用 plotxy 绘制横纵坐标值，其中纵坐标为 opinion 值的绝对值（保留 3 位精度）
; ========================================================================
to update-fdz
  ; 根据当前反对者数，设置 x 轴范围
  set-plot-x-range (-10 + (-1) * count turtles with [opinion < 0]) (10 + count turtles with [opinion > 0])
  let aggresive-list sort-on [opinion] turtles with [opinion < 0 and marked? != 2]
  ask turtles with [opinion < 0 and marked? != 2] [
    let x position self aggresive-list
    set whom x - length aggresive-list
    plotxy whom precision abs opinion 3
  ]
end

; ========================================================================
; x 轴绘图更新（支持者部分）：update-zcz
; ------------------------------------------------------------------------
; 同上，针对支持者的排序、位置赋值及绘图
; ========================================================================
to update-zcz
  set-plot-x-range (-10 + (-1) * count turtles with [opinion < 0]) (10 + count turtles with [opinion > 0])
  let positive-list sort-on [opinion] turtles with [opinion >= 0 and marked? != 2]
  ask turtles with [opinion >= 0 and marked? != 2] [
    let x position self positive-list
    set whom x
    plotxy whom precision opinion 3
  ]
end
@#$#@#$#@
GRAPHICS-WINDOW
378
19
907
549
-1
-1
5.16
1
10
1
1
1
0
1
1
1
-50
50
-50
50
0
0
1
ticks
30.0

BUTTON
6
10
72
43
NIL
setup\n
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1

BUTTON
7
55
70
88
NIL
go
T
1
T
OBSERVER
NIL
NIL
NIL
NIL
1

BUTTON
5
97
86
130
go once
go
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1

SLIDER
5
143
177
176
num-of-residents
num-of-residents
0
1000
500.0
1
1
NIL
HORIZONTAL

SLIDER
6
193
179
226
social-closeness
social-closeness
0
25
20.0
1
1
NIL
HORIZONTAL

SLIDER
5
238
177
271
social-repulsion
social-repulsion
0
100
76.0
1
1
NIL
HORIZONTAL

SLIDER
4
281
176
314
initial-protest-size
initial-protest-size
0
1
0.8
0.01
1
NIL
HORIZONTAL

SLIDER
6
330
178
363
socializing-scale
socializing-scale
0
20
6.0
1
1
NIL
HORIZONTAL

SLIDER
6
373
288
406
average-chance-of-being-affected
average-chance-of-being-affected
0
100
30.0
1
1
%
HORIZONTAL

PLOT
6
414
320
595
opinion-distribution
NIL
NIL
0.0
10.0
0.0
1.0
true
true
"" ""
PENS
"pros" 1.0 0 -13345367 true "" "update-plot-pros"
"cons" 1.0 0 -2674135 true "" "update-plot-cons"
"silents" 1.0 0 -7500403 true "" "update-plot-silents"

SLIDER
189
144
361
177
silent-inclination
silent-inclination
0
100
25.0
5
1
NIL
HORIZONTAL

MONITOR
378
550
456
595
num-cons
count cons
17
1
11

MONITOR
477
549
554
594
num-pros
count pros
17
1
11

MONITOR
575
549
663
594
num-silents
count silents
17
1
11

SWITCH
918
13
1089
46
make-declaration?
make-declaration?
1
1
-1000

MONITOR
191
327
315
372
num-declarations
count patches with[pcolor = blue]
17
1
11

SLIDER
189
193
362
226
government-credibility
government-credibility
0
1
0.7
0.01
1
NIL
HORIZONTAL

BUTTON
918
151
1046
184
NIL
coordinator
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1

INPUTBOX
919
228
1068
288
clear-n-of-coordinators
5.0
1
0
Number

BUTTON
918
192
1060
225
NIL
clear-coordinator\n
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1

MONITOR
191
275
285
320
coordinators
count turtles with [marked? = 2]
17
1
11

PLOT
920
291
1255
531
rate-of-transformation
NIL
NIL
0.0
10.0
-5.0
5.0
true
true
"" ""
PENS
"cons" 1.0 0 -2674135 true "" "carefully [update-derivative-of-cons][print error-message]"
"pros" 1.0 0 -13345367 true "" "carefully [update-derivative-of-pros][print error-message]"
"silents" 1.0 0 -7500403 true "" "carefully [update-derivative-of-silents][print error-message]"

SLIDER
190
236
362
269
m
m
0
6
4.0
1
1
NIL
HORIZONTAL

SWITCH
915
63
1077
96
go-to-influencer
go-to-influencer
1
1
-1000

SWITCH
917
112
1220
145
go-to-the-most-aggressive-protestors
go-to-the-most-aggressive-protestors
1
1
-1000

MONITOR
673
549
1257
594
NIL
kcorelist
17
1
11

BUTTON
1052
151
1246
184
keep-defining-influencers
;;持续寻找influencers\n;;每个tick重新找一次\nif ticks mod 3 = 0 [\nask turtles [\nset fake-dead? false\nset die?? false\n\n]\nset kcorelist [ ]\nset is-core-matched-flag? false\nset run-flag? true\n]\n\n\n
T
1
T
OBSERVER
NIL
NIL
NIL
NIL
1

SWITCH
1107
12
1257
45
hatch-rumors?
hatch-rumors?
1
1
-1000

PLOT
378
602
848
749
rumors-generation
NIL
NIL
0.0
20.0
0.0
10.0
true
true
"set-plot-x-range 1 5" "carefully [set-plot-x-range 1 max[generation] of rumors ][set-plot-x-range 1 5]\nset-plot-y-range 0 500"
PENS
"generations" 1.0 1 -8630108 true "" " histogram [generation] of rumors\n set-plot-pen-color violet\n"

PLOT
867
598
1494
770
how-different-the-rumors-are?
NIL
NIL
0.0
10.0
0.0
1.0
true
true
"" ""
PENS
"types" 1.0 0 -10141563 true "" "carefully [plot count rumors with [original?] / count rumors][\nplot 0]\n"
"rumors" 1.0 0 -2674135 true "" "carefully[plot count rumors / 10201][plot 0]"
"declarations" 1.0 0 -13345367 true "" "carefully [plot count declaration / 10201][plot 0]"

PLOT
6
602
322
745
types
NIL
NIL
0.0
10.0
0.0
10.0
true
true
"" ""
PENS
"gen1" 1.0 0 -955883 true "" "plot count rumors with[generation = 1]\n"
"all-types" 1.0 0 -7500403 true "" "plot count rumors with[original?]"

PLOT
6
763
324
952
accumulated-dead-rumors
NIL
NIL
0.0
10.0
0.0
10.0
true
true
"" ""
PENS
"dead-rumors" 1.0 0 -10402772 true "" "plot dead-rumors"

PLOT
1262
291
1460
530
dead-rumors-types
NIL
NIL
0.0
10.0
0.0
10.0
true
false
"" ""
PENS
"default" 1.0 0 -5298144 true "" "plot dead-rumors-types"

PLOT
377
764
854
1098
risk-perception-distribution
NIL
NIL
-10.0
10.0
0.0
10.0
true
true
"" "set-plot-x-range ((-1) * count turtles with[opinion < 0]) (count turtles with[opinion > 0])\n;set-plot-y-range 0  max [abs opinion] of turtles with[marked? != 2]"
PENS
"neg-perception" 1.0 2 -2674135 true "" "update-fdz\n"
"pos-perception" 1.0 2 -13345367 true "" "update-zcz"

PLOT
1500
548
1771
770
standard-deviation
NIL
NIL
0.0
10.0
0.0
10.0
true
false
"" ""
PENS
"all" 1.0 0 -16777216 true "" "plot standard-deviation [opinion] of turtles"
"neg" 1.0 0 -2674135 true "" "if count turtles with[opinion < 0 and marked? != 2] >= 2[\nplot standard-deviation [opinion] of turtles with[\nopinion < 0 and marked? != 2]]"
"pos" 1.0 0 -13345367 true "" "if count turtles with[opinion > 0 and marked? != 2] >= 2[\nplot standard-deviation [opinion] of turtles with[\nopinion > 0 and marked? != 2]]"

TEXTBOX
363
735
551
758
NIL
11
0.0
1

PLOT
1468
291
1764
530
extreme-plot
NIL
NIL
0.0
10.0
-10.0
-80.0
true
false
"" ""
PENS
"pros-mean" 1.0 0 -2674135 true "" "plot min [opinion] of turtles with [marked? != 2 ]"

PLOT
867
778
1244
996
government-credibility
NIL
NIL
0.0
10.0
0.0
1.0
true
false
"" ""
PENS
"default" 1.0 0 -10899396 true "" "plot government-credibility"

MONITOR
1085
189
1213
234
rumors-gen1
count rumors with[generation = 1]
17
1
11

MONITOR
1085
243
1213
288
rumors-of-all-types
count rumors with[original?]
17
1
11

@#$#@#$#@
## WHAT IS IT?

(a general understanding of what the model is trying to show or explain)

## HOW IT WORKS

(what rules the agents use to create the overall behavior of the model)

## HOW TO USE IT

(how to use the model, including a description of each of the items in the Interface tab)

## THINGS TO NOTICE

(suggested things for the user to notice while running the model)

## THINGS TO TRY

(suggested things for the user to try to do (move sliders, switches, etc.) with the model)

## EXTENDING THE MODEL

(suggested things to add or change in the Code tab to make the model more complicated, detailed, accurate, etc.)

## NETLOGO FEATURES

(interesting or unusual features of NetLogo that the model uses, particularly in the Code tab; or where workarounds were needed for missing features)

## RELATED MODELS

(models in the NetLogo Models Library and elsewhere which are of related interest)

## CREDITS AND REFERENCES

(a reference to the model's URL on the web if it has one, as well as any other necessary credits, citations, and links)
@#$#@#$#@
default
true
0
Polygon -7500403 true true 150 5 40 250 150 205 260 250

airplane
true
0
Polygon -7500403 true true 150 0 135 15 120 60 120 105 15 165 15 195 120 180 135 240 105 270 120 285 150 270 180 285 210 270 165 240 180 180 285 195 285 165 180 105 180 60 165 15

arrow
true
0
Polygon -7500403 true true 150 0 0 150 105 150 105 293 195 293 195 150 300 150

box
false
0
Polygon -7500403 true true 150 285 285 225 285 75 150 135
Polygon -7500403 true true 150 135 15 75 150 15 285 75
Polygon -7500403 true true 15 75 15 225 150 285 150 135
Line -16777216 false 150 285 150 135
Line -16777216 false 150 135 15 75
Line -16777216 false 150 135 285 75

bug
true
0
Circle -7500403 true true 96 182 108
Circle -7500403 true true 110 127 80
Circle -7500403 true true 110 75 80
Line -7500403 true 150 100 80 30
Line -7500403 true 150 100 220 30

butterfly
true
0
Polygon -7500403 true true 150 165 209 199 225 225 225 255 195 270 165 255 150 240
Polygon -7500403 true true 150 165 89 198 75 225 75 255 105 270 135 255 150 240
Polygon -7500403 true true 139 148 100 105 55 90 25 90 10 105 10 135 25 180 40 195 85 194 139 163
Polygon -7500403 true true 162 150 200 105 245 90 275 90 290 105 290 135 275 180 260 195 215 195 162 165
Polygon -16777216 true false 150 255 135 225 120 150 135 120 150 105 165 120 180 150 165 225
Circle -16777216 true false 135 90 30
Line -16777216 false 150 105 195 60
Line -16777216 false 150 105 105 60

car
false
0
Polygon -7500403 true true 300 180 279 164 261 144 240 135 226 132 213 106 203 84 185 63 159 50 135 50 75 60 0 150 0 165 0 225 300 225 300 180
Circle -16777216 true false 180 180 90
Circle -16777216 true false 30 180 90
Polygon -16777216 true false 162 80 132 78 134 135 209 135 194 105 189 96 180 89
Circle -7500403 true true 47 195 58
Circle -7500403 true true 195 195 58

circle
false
0
Circle -7500403 true true 0 0 300

circle 2
false
0
Circle -7500403 true true 0 0 300
Circle -16777216 true false 30 30 240

cow
false
0
Polygon -7500403 true true 200 193 197 249 179 249 177 196 166 187 140 189 93 191 78 179 72 211 49 209 48 181 37 149 25 120 25 89 45 72 103 84 179 75 198 76 252 64 272 81 293 103 285 121 255 121 242 118 224 167
Polygon -7500403 true true 73 210 86 251 62 249 48 208
Polygon -7500403 true true 25 114 16 195 9 204 23 213 25 200 39 123

cylinder
false
0
Circle -7500403 true true 0 0 300

dot
false
0
Circle -7500403 true true 90 90 120

face happy
false
0
Circle -7500403 true true 8 8 285
Circle -16777216 true false 60 75 60
Circle -16777216 true false 180 75 60
Polygon -16777216 true false 150 255 90 239 62 213 47 191 67 179 90 203 109 218 150 225 192 218 210 203 227 181 251 194 236 217 212 240

face neutral
false
0
Circle -7500403 true true 8 7 285
Circle -16777216 true false 60 75 60
Circle -16777216 true false 180 75 60
Rectangle -16777216 true false 60 195 240 225

face sad
false
0
Circle -7500403 true true 8 8 285
Circle -16777216 true false 60 75 60
Circle -16777216 true false 180 75 60
Polygon -16777216 true false 150 168 90 184 62 210 47 232 67 244 90 220 109 205 150 198 192 205 210 220 227 242 251 229 236 206 212 183

fish
false
0
Polygon -1 true false 44 131 21 87 15 86 0 120 15 150 0 180 13 214 20 212 45 166
Polygon -1 true false 135 195 119 235 95 218 76 210 46 204 60 165
Polygon -1 true false 75 45 83 77 71 103 86 114 166 78 135 60
Polygon -7500403 true true 30 136 151 77 226 81 280 119 292 146 292 160 287 170 270 195 195 210 151 212 30 166
Circle -16777216 true false 215 106 30

flag
false
0
Rectangle -7500403 true true 60 15 75 300
Polygon -7500403 true true 90 150 270 90 90 30
Line -7500403 true 75 135 90 135
Line -7500403 true 75 45 90 45

flower
false
0
Polygon -10899396 true false 135 120 165 165 180 210 180 240 150 300 165 300 195 240 195 195 165 135
Circle -7500403 true true 85 132 38
Circle -7500403 true true 130 147 38
Circle -7500403 true true 192 85 38
Circle -7500403 true true 85 40 38
Circle -7500403 true true 177 40 38
Circle -7500403 true true 177 132 38
Circle -7500403 true true 70 85 38
Circle -7500403 true true 130 25 38
Circle -7500403 true true 96 51 108
Circle -16777216 true false 113 68 74
Polygon -10899396 true false 189 233 219 188 249 173 279 188 234 218
Polygon -10899396 true false 180 255 150 210 105 210 75 240 135 240

house
false
0
Rectangle -7500403 true true 45 120 255 285
Rectangle -16777216 true false 120 210 180 285
Polygon -7500403 true true 15 120 150 15 285 120
Line -16777216 false 30 120 270 120

leaf
false
0
Polygon -7500403 true true 150 210 135 195 120 210 60 210 30 195 60 180 60 165 15 135 30 120 15 105 40 104 45 90 60 90 90 105 105 120 120 120 105 60 120 60 135 30 150 15 165 30 180 60 195 60 180 120 195 120 210 105 240 90 255 90 263 104 285 105 270 120 285 135 240 165 240 180 270 195 240 210 180 210 165 195
Polygon -7500403 true true 135 195 135 240 120 255 105 255 105 285 135 285 165 240 165 195

line
true
0
Line -7500403 true 150 0 150 300

line half
true
0
Line -7500403 true 150 0 150 150

pentagon
false
0
Polygon -7500403 true true 150 15 15 120 60 285 240 285 285 120

person
false
0
Circle -7500403 true true 110 5 80
Polygon -7500403 true true 105 90 120 195 90 285 105 300 135 300 150 225 165 300 195 300 210 285 180 195 195 90
Rectangle -7500403 true true 127 79 172 94
Polygon -7500403 true true 195 90 240 150 225 180 165 105
Polygon -7500403 true true 105 90 60 150 75 180 135 105

person business
false
0
Rectangle -1 true false 120 90 180 180
Polygon -13345367 true false 135 90 150 105 135 180 150 195 165 180 150 105 165 90
Polygon -7500403 true true 120 90 105 90 60 195 90 210 116 154 120 195 90 285 105 300 135 300 150 225 165 300 195 300 210 285 180 195 183 153 210 210 240 195 195 90 180 90 150 165
Circle -7500403 true true 110 5 80
Rectangle -7500403 true true 127 76 172 91
Line -16777216 false 172 90 161 94
Line -16777216 false 128 90 139 94
Polygon -13345367 true false 195 225 195 300 270 270 270 195
Rectangle -13791810 true false 180 225 195 300
Polygon -14835848 true false 180 226 195 226 270 196 255 196
Polygon -13345367 true false 209 202 209 216 244 202 243 188
Line -16777216 false 180 90 150 165
Line -16777216 false 120 90 150 165

person soldier
false
0
Rectangle -7500403 true true 127 79 172 94
Polygon -10899396 true false 105 90 60 195 90 210 135 105
Polygon -10899396 true false 195 90 240 195 210 210 165 105
Circle -7500403 true true 110 5 80
Polygon -10899396 true false 105 90 120 195 90 285 105 300 135 300 150 225 165 300 195 300 210 285 180 195 195 90
Polygon -6459832 true false 120 90 105 90 180 195 180 165
Line -6459832 false 109 105 139 105
Line -6459832 false 122 125 151 117
Line -6459832 false 137 143 159 134
Line -6459832 false 158 179 181 158
Line -6459832 false 146 160 169 146
Rectangle -6459832 true false 120 193 180 201
Polygon -6459832 true false 122 4 107 16 102 39 105 53 148 34 192 27 189 17 172 2 145 0
Polygon -16777216 true false 183 90 240 15 247 22 193 90
Rectangle -6459832 true false 114 187 128 208
Rectangle -6459832 true false 177 187 191 208

plant
false
0
Rectangle -7500403 true true 135 90 165 300
Polygon -7500403 true true 135 255 90 210 45 195 75 255 135 285
Polygon -7500403 true true 165 255 210 210 255 195 225 255 165 285
Polygon -7500403 true true 135 180 90 135 45 120 75 180 135 210
Polygon -7500403 true true 165 180 165 210 225 180 255 120 210 135
Polygon -7500403 true true 135 105 90 60 45 45 75 105 135 135
Polygon -7500403 true true 165 105 165 135 225 105 255 45 210 60
Polygon -7500403 true true 135 90 120 45 150 15 180 45 165 90

sheep
false
15
Circle -1 true true 203 65 88
Circle -1 true true 70 65 162
Circle -1 true true 150 105 120
Polygon -7500403 true false 218 120 240 165 255 165 278 120
Circle -7500403 true false 214 72 67
Rectangle -1 true true 164 223 179 298
Polygon -1 true true 45 285 30 285 30 240 15 195 45 210
Circle -1 true true 3 83 150
Rectangle -1 true true 65 221 80 296
Polygon -1 true true 195 285 210 285 210 240 240 210 195 210
Polygon -7500403 true false 276 85 285 105 302 99 294 83
Polygon -7500403 true false 219 85 210 105 193 99 201 83

square
false
0
Rectangle -7500403 true true 30 30 270 270

square 2
false
0
Rectangle -7500403 true true 30 30 270 270
Rectangle -16777216 true false 60 60 240 240

star
false
0
Polygon -7500403 true true 151 1 185 108 298 108 207 175 242 282 151 216 59 282 94 175 3 108 116 108

target
false
0
Circle -7500403 true true 0 0 300
Circle -16777216 true false 30 30 240
Circle -7500403 true true 60 60 180
Circle -16777216 true false 90 90 120
Circle -7500403 true true 120 120 60

tree
false
0
Circle -7500403 true true 118 3 94
Rectangle -6459832 true false 120 195 180 300
Circle -7500403 true true 65 21 108
Circle -7500403 true true 116 41 127
Circle -7500403 true true 45 90 120
Circle -7500403 true true 104 74 152

triangle
false
0
Polygon -7500403 true true 150 30 15 255 285 255

triangle 2
false
0
Polygon -7500403 true true 150 30 15 255 285 255
Polygon -16777216 true false 151 99 225 223 75 224

truck
false
0
Rectangle -7500403 true true 4 45 195 187
Polygon -7500403 true true 296 193 296 150 259 134 244 104 208 104 207 194
Rectangle -1 true false 195 60 195 105
Polygon -16777216 true false 238 112 252 141 219 141 218 112
Circle -16777216 true false 234 174 42
Rectangle -7500403 true true 181 185 214 194
Circle -16777216 true false 144 174 42
Circle -16777216 true false 24 174 42
Circle -7500403 false true 24 174 42
Circle -7500403 false true 144 174 42
Circle -7500403 false true 234 174 42

turtle
true
0
Polygon -10899396 true false 215 204 240 233 246 254 228 266 215 252 193 210
Polygon -10899396 true false 195 90 225 75 245 75 260 89 269 108 261 124 240 105 225 105 210 105
Polygon -10899396 true false 105 90 75 75 55 75 40 89 31 108 39 124 60 105 75 105 90 105
Polygon -10899396 true false 132 85 134 64 107 51 108 17 150 2 192 18 192 52 169 65 172 87
Polygon -10899396 true false 85 204 60 233 54 254 72 266 85 252 107 210
Polygon -7500403 true true 119 75 179 75 209 101 224 135 220 225 175 261 128 261 81 224 74 135 88 99

wheel
false
0
Circle -7500403 true true 3 3 294
Circle -16777216 true false 30 30 240
Line -7500403 true 150 285 150 15
Line -7500403 true 15 150 285 150
Circle -7500403 true true 120 120 60
Line -7500403 true 216 40 79 269
Line -7500403 true 40 84 269 221
Line -7500403 true 40 216 269 79
Line -7500403 true 84 40 221 269

wolf
false
0
Polygon -16777216 true false 253 133 245 131 245 133
Polygon -7500403 true true 2 194 13 197 30 191 38 193 38 205 20 226 20 257 27 265 38 266 40 260 31 253 31 230 60 206 68 198 75 209 66 228 65 243 82 261 84 268 100 267 103 261 77 239 79 231 100 207 98 196 119 201 143 202 160 195 166 210 172 213 173 238 167 251 160 248 154 265 169 264 178 247 186 240 198 260 200 271 217 271 219 262 207 258 195 230 192 198 210 184 227 164 242 144 259 145 284 151 277 141 293 140 299 134 297 127 273 119 270 105
Polygon -7500403 true true -1 195 14 180 36 166 40 153 53 140 82 131 134 133 159 126 188 115 227 108 236 102 238 98 268 86 269 92 281 87 269 103 269 113

x
false
0
Polygon -7500403 true true 270 75 225 30 30 225 75 270
Polygon -7500403 true true 30 75 75 30 270 225 225 270
@#$#@#$#@
NetLogo 6.4.0
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
default
0.0
-0.2 0 0.0 1.0
0.0 1 1.0 0.0
0.2 0 0.0 1.0
link direction
true
0
Line -7500403 true 150 150 90 180
Line -7500403 true 150 150 210 180
@#$#@#$#@
0
@#$#@#$#@
